package com.ltu.redis.lock;

//import java.util.Iterator;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
//import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import com.ltu.base.State;
//import com.ltu.domain.mp_entity.AccountEntity;
import com.ltu.util.exception.ApiException;
import com.ltu.util.redis.RedisKeyManager;
import com.ltu.util.redis.RedistUtil;

//import lombok.RequiredArgsConstructor;


/**
 * 并发控制扣减剩余可报名的队伍数量
 * @author Administrator
 *
 */
@Component("productStoceLock")
public class ProductStoceLock implements AmountLockService {

//	private final  ProductMapper  productMapper;
	private final RedissonClient redissonClient;
	private final RedistUtil redistUtil;
	
	
//	public ProductStoceLock(RedistUtil redistUtil, RedissonClient redissonClient,ProductMapper productMapper) {
		public ProductStoceLock(RedistUtil redistUtil, RedissonClient redissonClient) {
//		this.productMapper = productMapper;
		this.redissonClient = redissonClient;
		this.redistUtil = redistUtil;
		
	}

	/**
	 * 加锁控制扣减 TeamsLimit 的数量
	 * 
	 * @param id
	 * @param fee
	 * @return
	 */
	public State syncJob(String id, Integer amount) {
		if (null == amount || StringUtils.isEmpty(id))
			return new State(State.CODE_FAILED, "组别ID必传");
		if (amount.equals(0) )
			 return State.AMOUNTERROR; 
		RLock lock = redissonClient.getLock(RedisKeyManager.AmountLockKey.concat(id));
		try {
			// 获取一个1000毫秒的锁
			boolean lockFlag = lock.tryLock(3L, 1L, TimeUnit.SECONDS);
			if (lockFlag) {
				Integer val = getAmount(id) + amount;
				if (val < 0)
					return State.AMOUNTERROR;
				String key = RedisKeyManager.AmountValKey.concat(id);
//				redistUtil.setValue(key, val);
				redistUtil.incrementBy(key, amount);
				return State.SUCCESS;
			}

		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (lock.isHeldByCurrentThread())
				lock.unlock();
		}
		return State.RETRY;

	}
	
	
	/**
	 * 加锁访问获取值
	 * 
	 * @param id
	 * @return
	 */
	private Integer getAmount(String id) {
		String key = RedisKeyManager.AmountValKey.concat(id);
		Integer val = null;
		if (!redistUtil.containsKey(key)) {
//			ProductEntity target = productMapper.selectById(id);
//			redistUtil.setValue(key, target.getSurplusAmount());
//			val = target.getSurplusAmount();
		} else
			val = (Integer) redistUtil.getValue(key);
		return val;
	}

	/**
	 * 加锁控制写入redis
	 * 
	 * @param id
	 * @return
	 */
	@Override
	public void setAmount(String id, Integer amount) {
		//
		RLock lock = redissonClient.getLock(RedisKeyManager.AmountLockKey.concat(id));
		try {
			// 获取一个1000毫秒的锁
			boolean lockFlag = lock.tryLock(2L, 1L, TimeUnit.SECONDS);
			if (lockFlag) {
				String key = RedisKeyManager.AmountValKey.concat(id);
				redistUtil.setValue(key, amount);
			} else
				throw new ApiException("人数过多请稍后再试");

		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (lock.isHeldByCurrentThread())
				lock.unlock();
		}
	}
	
	/**
	 * 加锁控制写入redis
	 * @param id
	 * @return
	 */
	@Async("customServiceExecutor")
	@Override
	public void rollbackAmount(String id, Integer amount) {
		//
		RLock lock = redissonClient.getLock(RedisKeyManager.AmountLockKey.concat(id));
		try {
			// 获取一个1000毫秒的锁
			boolean lockFlag = lock.tryLock(2L, 1L, TimeUnit.SECONDS);
			if (lockFlag ) {
				String key = RedisKeyManager.AmountValKey.concat(id);
				if(!redistUtil.containsKey(key))
					return;
				redistUtil.incrementBy(key, amount);
				lock.unlock();
				return;
			} else {
				Thread.currentThread().sleep(300l);
				rollbackAmount(id, amount);
			}
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (lock.isHeldByCurrentThread())
					lock.unlock();
		}
	}

}
